package com.msconfig.device;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;

import com.geo.msconfig.R;
import com.geo.parse.CDataParseManage;
import com.geo.parse.GnssLocationData;
import com.geo.parse.GnssOutputListener;
import com.geo.parse.GnssPoseSensorData;
import com.geo.parse.GnssRefStationData;
import com.geo.parse.GnssSateInfoList;
import com.msconfig.MyApplication;
import com.msconfig.bean.deviceInfoBean.TagDeviceInfo;
import com.msconfig.event.DeviceUpdateUINotify;
import com.msconfig.event.IsSaveConfigFileGetAllEvent;
import com.msconfig.event.TimeZoneDialogDismissEvent;
import com.msconfig.io.BlueToothIo;
import com.msconfig.io.ConnectListener;
import com.msconfig.io.DataIoInterface;
import com.msconfig.io.DeviceLinkerType;
import com.msconfig.io.ReceiverListener;
import com.msconfig.io.RtkResponseDataListener;
import com.msconfig.mvp.view.adapter.ConfigAdapter;
import com.msconfig.utils.GeneralUtil;
import com.msconfig.utils.WriteToFileUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Date;

import static com.msconfig.io.BlueToothIo.debugName;

public class DeviceManage {
	//用于单例模式
	private static DeviceManage mDeviceManage = null;

	// 参数是否足够进行连接;
	private boolean mbConnectable = false;
	// 设备库IO部分;
	private DataIoInterface mDataIoInterface = null;
	// GPS原始数据解析;
	private CDataParseManage mGnssParseManage = null;

	private WifiManager mWifi;

	private Context mContext = null;

	private CommandParseManage mCommandParseManage = CommandParseManage.getInstance();

	// 接收数据回调, 用于向测试页面发信息;
	private ReceiverListener receiverListener = null;
	private RtkResponseDataListener responseDataListener = null;

	// 是否已经连接上设备;
	private ConnectListener.CommanderStatus mConnectedStatus = ConnectListener.CommanderStatus.FAIL;

	//开始启动线程监听自动连接
	public void startAutoConnectRunnable() {
		mHandler.postDelayed(mRunnable, 1000);
	}

	//接收数据监听
	public void RegReceiverListener(ReceiverListener listener) {
		receiverListener = listener;
	}

	//接收rtk数据监听
	public void RegRtkRespondDataListener(RtkResponseDataListener listener) {
		responseDataListener = listener;
	}

	//断开接收数据监听
	public void UnReceiverListener() {
		receiverListener = null;
	}

	// 单例模式获取实例;
	public static DeviceManage getInstance() {
		if (mDeviceManage == null) {
			mDeviceManage = new DeviceManage();
			//注册监听
			mDeviceManage.mGnssParseManage = new CDataParseManage();
			mDeviceManage.mGnssParseManage.RegGnssOutputListener(mDeviceManage.mGnssOutputListener);
			//选择连接方式，new具体的实例
			mDeviceManage.setDeviceConnectType(DeviceLinkerType.BLUETOOTH);
		}
		return mDeviceManage;
	}

	// 选择连接方式 ;
	private void setDeviceConnectType(DeviceLinkerType deviceLinkerType) {
		if (deviceLinkerType == null) {
			return;
		}
		// 设备选择没变化;
		if (mDataIoInterface != null && mDataIoInterface.getDeviceType() == deviceLinkerType) {
			return;
		}
		if (mDataIoInterface != null)
			mDataIoInterface.disConnect();

		switch (deviceLinkerType) {
			case BLUETOOTH:
				mDataIoInterface = new BlueToothIo();
				break;
			default:
				break;
		}

		// 注册数据回调;
		if (mDataIoInterface != null) {
			mDataIoInterface.regReceiverListener(mReceiverListener);
		}
	}

	// 接收数据回调;
	private ReceiverListener mReceiverListener = new ReceiverListener() {
		@Override
		public void OnReceiverCallBack(int nLength, byte[] data) {
			Log.d("OnReceiverCallBack", new String(data,0,nLength));
			if (receiverListener != null) {
				receiverListener.OnReceiverCallBack(nLength, data);
			}
			if (mGnssParseManage.ProcessParse(data, nLength)) {
			}
		}
	};



	// 接收NMEA解析后数据 ;
	private GnssOutputListener mGnssOutputListener = new GnssOutputListener() {
		@Override
		public void OnGnssLocationCallBack(GnssLocationData location) {
			synchronized (GeoLocationData.locationLock) {
				GeoLocationData.getInstance().setLocationData(location);
				// 通知定位信息界面;
				DeviceUpdateUINotify.eventUpdateLocationResult();
			}
		}

		@Override
		public void OnGnssRefStationCallBack(GnssRefStationData refStation) {
			synchronized (GeoLocationData.locationLock) {
				try {
					GeoLocationData.getInstance().setRefStationData(refStation);
				}catch (Exception e) {

				}
			}
		}

		@Override
		public void OnGnssPoseSensorCallBack(GnssPoseSensorData poseSensor) {
		}

		@Override
		public void OnGnssSateInfoBack(GnssSateInfoList sateInfoList) {
			synchronized (GeoLocationData.locationLock) {
				try {
					GeoLocationData.getInstance().setSateInfoList(sateInfoList);
					// 通知星球星表界面;
					DeviceUpdateUINotify.eventUpdateSatelliteResult();
				}catch (Exception e){
				}
			}
		}

		@Override
		public void OnRtkRespondBack(String strGnssLine) {
			try {
				Log.d("OnRtkRespondBack", strGnssLine);
				//保存配置信息到文件中
				if (responseDataListener != null) {
					responseDataListener.OnRtkResponseCallBack(strGnssLine);
				}

				//解析每一行数据
				boolean isParseOk=mCommandParseManage.parseCommaneLine(strGnssLine);

				//不需要考虑重传的命令
				//获得数据回传状态更新信息,没有通过setSendCommandList方式发送，直接发送数据
				//包含成功或者失败的数据
				if(strGnssLine.contains("@GNSS,GET,DEVICE.RAW.RESULT_STATUS")){
					if(isParseOk){//return ok
						DeviceUpdateUINotify.eventUpdateDialogGetDataRawResultSucc();
					}
                    return;//不执行后面重传的判断
                }else if(strGnssLine.contains("@GNSS,GET,DEVICE.POWER_LEVEL")){//获得电池电量信息通知设备信息页面
				    if(isParseOk){
                        DeviceUpdateUINotify.eventUpdateDialogGetPowerLevelSucc();
                    }
					return;
				}

                //刚开始连接的时候显示连接对话框，GETALL ok之后给那边通知获取RTK成功
                if(strGnssLine.equals(MyApplication.getGlobalContext().getString(R.string.command_gnss_getall_ok))){
                    DeviceUpdateUINotify.eventUpdateDialogGetRtkSuccess();
                }
				//处理回复数据判断需不需要重新发送
				CommandSendManage.getInstance().processRtkBackCommand(strGnssLine);
			}catch (Exception e){}
		}
	};

	//1.设置要连接的设备
	public boolean setSelectedDevice(String device) {
		if (mDataIoInterface == null)
			return false;  // 还未选数据链或者选的是local;
		mbConnectable = mDataIoInterface.setDevice(device);
		return mbConnectable;
	}

	//2给外部调用--连接设备
	public boolean connect() {
		if (mDataIoInterface == null)
			return false;//还未选数据链;
		//如果当前连接成功,就不给继续连接;
		if (DeviceManage.getInstance().isConnected()) {
			return false;
		}
		mConnectedStatus = ConnectListener.CommanderStatus.STATE;
		mDataIoInterface.regConnectListener(mConnectListener);
		mDataIoInterface.connect();
		return true;
	}

	//连接回调;
	private ConnectListener mConnectListener = new ConnectListener() {
		@Override
		public void OnConnectCallBack(boolean bSucceed) {
			mConnectedStatus = bSucceed?CommanderStatus.SUCCESS : CommanderStatus.FAIL;
			//通知界面连接成功还是失败
			DeviceUpdateUINotify.eventDeviceConnectResult(bSucceed);
			//连接成功了，发GETALL命令到主机
			if (bSucceed)
			{
				//连接成功的话，注册自动重连
				mAutoDisconnect=true;
				startAutoConnectRunnable();
				//得到发送命令的集合
				ArrayList<TagSendCommand> sendCommandList= GetSendCommandList.getGetAllCommandList();
				//设置发送命令额集合
				CommandSendManage.getInstance().setSendCommandList(sendCommandList);
				//开始发送命令
				CommandSendManage.getInstance().startSendCommand();
			}
		}

		@Override
		public void OnDisConnectCallBack() {
			mConnectedStatus = CommanderStatus.FAIL;
			// 调用断开事件;
			DeviceUpdateUINotify.eventDeviceDisConnectResult();
			mGnssParseManage.Initialize();
			// 断开连接清空数据;
			GeoLocationData.getInstance().resetGnssData();
		}
	};



	//断开连接;
	public boolean disConnect() {
		if (mDataIoInterface == null)
			return false;  // 还未选数据链;
		mDataIoInterface.disConnect();
		return true;
	}

	//是手动断开还是自动断开
	public void setAutoDisconnect(boolean isAutoDisconnect) {
		mAutoDisconnect = isAutoDisconnect;
	}



	//连接成功后在这里线程处理处理自动连接;
	private boolean mAutoDisconnect = true;//默认是自动断开的
	private Handler mHandler = new Handler();
	private Runnable mRunnable = new Runnable() {
		int nPowerOverTimeCount = 30;
		@Override
		public void run() {
			//判断定位数据是不是有效的，可能长时间无数据
			GeoLocationData.getInstance().isValidate();
			nPowerOverTimeCount--;
			//判断有没有断开来进行自动重连
			if(!DeviceManage.getInstance().isConnected()){
				if(mAutoDisconnect){//代表自动断开，重新连接
					//通知页面进行自动重连
					mDataIoInterface.lodDebug("Auto reconnect");
					DeviceUpdateUINotify.eventAutoConnect();
					mAutoDisconnect=false;
				}
			}

			if (nPowerOverTimeCount < 0) {
				//每隔30秒钟，发送一次获取当前电池电量;
				//得到发送命令的集合
				ArrayList<TagSendCommand> sendCommandList= GetSendCommandList.getPowerLevel();
				//设置发送命令额集合
				CommandSendManage.getInstance().setSendCommandList(sendCommandList);
				//开始发送命令
				CommandSendManage.getInstance().startSendCommand();
				nPowerOverTimeCount = 30;
			}

			mHandler.postDelayed(this, 1000);
		}
	};

	//得到连接设备的名字
	public String getDeviceName() {
		if (mDataIoInterface == null) return "";
		return  mDataIoInterface.getDevice();
	}

	//连接设备状态;
	public ConnectListener.CommanderStatus getConnectedStatus() {
		return mConnectedStatus;
	}

	//判断是否连接
	public boolean isConnected(){
		if(ConnectListener.CommanderStatus.SUCCESS == DeviceManage.getInstance().getConnectedStatus()){
			return true;
		}else{
			return false;
		}
	}

	// 发送命令; 
	public boolean sendCommand(String strCommand) {
		if (mDataIoInterface == null || strCommand == null || strCommand.isEmpty())
			return false;//还未选数据链

		return mDataIoInterface.sendData(strCommand);
	}

	//用户将配置参数显示到界面
	public TagDeviceInfo getDeviceInfo()
	{
		return mCommandParseManage.getDeviceInfo();
	}

}
